/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
/**
 * Software License, Version 1.0
 * 
 * Copyright 2004 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.gridapps.nbgridftp.subscriber;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.ProgressMonitorInputStream;

import org.globus.ftp.Buffer;
import org.globus.ftp.DataSource;
import org.globus.ftp.GridFTPClient;
import org.globus.ftp.GridFTPSession;
import org.gridforum.jgss.ExtendedGSSManager;
import org.ietf.jgss.GSSCredential;
/**
   @author Sang Boem Lim
   $Date$
   $Revision$
 */
public class NB2ServerData extends Thread {
    private static final int ANY_PORT = 0;
    private static final int DEFAULT_QUEUE = 100;

    private String host;
    private String port;

    private static InputStream fromServer;
    private static OutputStream toServer;
    private ServerSocket server;

    private final String FSD = "From server data: ";

    public NB2ServerData() {

        try {
            server = new ServerSocket(ANY_PORT, DEFAULT_QUEUE);

            host = server.getInetAddress().getLocalHost().getHostAddress();
            port = "" + server.getLocalPort();


        } catch (Exception e){
            System.err.println(e);
            System.exit(1);
        }
    }

    public static void close2Server() {
        try {
            toServer.close();
        } catch(IOException e){
            System.err.println("NB2ServerData::close2Server:"+e);
        }
    }

    private static boolean finished = true;
    public synchronized boolean isFinished() {

        return finished;
    }

    public static synchronized void setFinished(boolean fin) {

        finished = fin;
    }

    public void run() {
        try {
            Socket s = server.accept();
            
            fromServer = s.getInputStream();
            toServer   = s.getOutputStream();

            // looking for temporary diractory to store file. If this
            // diractory is not present, create one.

            String clientName = s.getInetAddress().getHostAddress() + ":" + 
                s.getPort();

            int bytes_read;
            byte[] request = new byte[1024];
            
            while((bytes_read = fromServer.read(request)) != -1)
                NB2ServerControl.writeMessage(request, bytes_read, FSD);
            
        } catch (IOException e) {
            
            close();
        } catch (javax.jms.JMSException e){
            System.err.println(e);
        }
    }

    
    public static void write2Server(byte[] message, int length) {

        try {
            toServer.write(message, 0, length);
            toServer.flush();
        } catch (IOException e) {
            close();
        }
    }

    private static void writeData(byte[] message, int length) 
        throws IOException, RecoverException {

        if(toServer != null) {
            toServer.write(message, 0, length);
            toServer.flush();
        } else 
            throw new RecoverException();
    }

    public static void sendData(String localFile, String host, int port) {

        try {
            byte[] inFile = new byte[3072];
            ProgressMonitorInputStream monitor = 
                new ProgressMonitorInputStream(null,
                                               "Loading " + localFile,
                                               new FileInputStream(localFile));
            
            while (monitor.available() > 0) {
                
                int length = monitor.read(inFile);
                NB2ServerData.writeData(inFile, length);
            }
            
            monitor.close();
            
            close2Server();
            
            setFinished(true);
        } catch (java.io.FileNotFoundException e) {
            
        } catch (java.io.IOException e) {

        } catch (RecoverException e) {
            try {
                ExtendedGSSManager manager =
                    (ExtendedGSSManager)ExtendedGSSManager.getInstance();
                
                GSSCredential cred =
                    manager.createCredential(GSSCredential.INITIATE_AND_ACCEPT);
                
                GridFTPClient client = new GridFTPClient(host, port);
                client.authenticate(cred);
                
                client.setType(GridFTPSession.TYPE_IMAGE);
                client.setMode(GridFTPSession.MODE_STREAM);
                
                client.setLocalPassive();
                client.setActive();
                
                final ProgressMonitorInputStream in = 
                    new ProgressMonitorInputStream(null,
                                                   "Loading "+localFile, 
                                                   new FileInputStream(localFile));

                client.put(localFile.substring(localFile.indexOf('%')).replace('%','/'), new DataSource(){
                        long totalRead = 0;
                        public synchronized Buffer read()
                            throws IOException
                            {
                                byte[] buf = new byte[1024];
                                int count;
                                if ((count = in.read(buf)) > 0) {

                                    Buffer buffer = new Buffer(buf, count, 
                                                               totalRead);
                                    totalRead += count;
                                    
                                    return buffer;
                                } else
                                    return null;
                            }
                        public void close() throws IOException
                            {
                                // close File input streams
                                in.close();
                            };
                    },null);
                
                client.close();

                NB2ServerControl.cleanup();
                NB2ServerControl.writeMessage(new byte[0], 0, "SERVER CLOSED: ");
            } catch (Exception se) {
                new Information().showError("Fail to transfer file "+
                                            localFile + ".");
            }
        }
    }
    
    public String getHostPort() {
        
        return host + ":" + port;
    }

    public static void close() {

        try {

            if (toServer != null) toServer.close();
            if (fromServer != null) fromServer.close();
        } catch (IOException e){
        }
    }
}
